X-Git-Url: https://git.r.bdr.sh/rbdr/map/blobdiff_plain/fdb4633d3e9158e457d57e820df6e1efb4df39c2..e2c37ac1dd2ad562e3d619d39b72a174a2212b67:/Map/Presentation/Base%20Components/MapTextEditor.swift diff --git a/Map/Presentation/Base Components/MapTextEditor.swift b/Map/Presentation/Base Components/MapTextEditor.swift index f3838a6..d7aa9f8 100644 --- a/Map/Presentation/Base Components/MapTextEditor.swift +++ b/Map/Presentation/Base Components/MapTextEditor.swift @@ -3,7 +3,7 @@ import SwiftUI class MapTextEditorController: NSViewController { - @Binding var text: String + @Binding var document: MapDocument let onChange: () -> Void private let vertexRegex = MapParsingPatterns.vertex @@ -12,11 +12,12 @@ class MapTextEditorController: NSViewController { private let opportunityRegex = MapParsingPatterns.opportunity private let noteRegex = MapParsingPatterns.note private let stageRegex = MapParsingPatterns.stage + private let groupRegex = MapParsingPatterns.group private let changeDebouncer: Debouncer = Debouncer(seconds: 1) - init(text: Binding, onChange: @escaping () -> Void) { - self._text = text + init(document: Binding, onChange: @escaping () -> Void) { + self._document = document self.onChange = onChange super.init(nibName: nil, bundle: nil) } @@ -31,10 +32,11 @@ class MapTextEditorController: NSViewController { scrollView.translatesAutoresizingMaskIntoConstraints = false + textView.backgroundColor = .ui.background textView.allowsUndo = true textView.delegate = self textView.textStorage?.delegate = self - textView.string = self.text + textView.string = self.document.text textView.isEditable = true textView.font = .monospacedSystemFont(ofSize: 16.0, weight: .regular) self.view = scrollView @@ -49,14 +51,13 @@ extension MapTextEditorController: NSTextViewDelegate { func textDidChange(_ obj: Notification) { if let textField = obj.object as? NSTextView { - self.text = textField.string - - - changeDebouncer.debounce { - DispatchQueue.main.async { - self.onChange() - } + self.document.text = textField.string + + changeDebouncer.debounce { + DispatchQueue.main.async { + self.onChange() } + } } } @@ -86,65 +87,91 @@ extension MapTextEditorController: NSTextStorageDelegate { var matches = vertexRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { - textStorage.addAttributes([.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 1)) - textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 2)) - textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 3)) - textStorage.addAttributes([.foregroundColor: NSColor.syntax.option], range: match.range(at: 4)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 1)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.number], range: match.range(at: 2)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.number], range: match.range(at: 3)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.option], range: match.range(at: 4)) } matches = edgeRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { - textStorage.addAttributes([.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 1)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 1)) let arrowRange = match.range(at: 2) textStorage.addAttributes( [.foregroundColor: NSColor.syntax.symbol], range: NSMakeRange(arrowRange.lowerBound - 1, arrowRange.length + 1)) - textStorage.addAttributes([.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 3)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 3)) } matches = opportunityRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { - textStorage.addAttributes([.foregroundColor: NSColor.syntax.option], range: match.range(at: 1)) - textStorage.addAttributes([.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 2)) - textStorage.addAttributes([.foregroundColor: NSColor.syntax.symbol], range: match.range(at: 3)) - textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 4)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.option], range: match.range(at: 1)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 2)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.symbol], range: match.range(at: 3)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.number], range: match.range(at: 4)) } matches = blockerRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { - textStorage.addAttributes([.foregroundColor: NSColor.syntax.option], range: match.range(at: 1)) - textStorage.addAttributes([.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 2)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.option], range: match.range(at: 1)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 2)) } - + matches = noteRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { - textStorage.addAttributes([.foregroundColor: NSColor.syntax.option], range: match.range(at: 1)) - textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 2)) - textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 3)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.option], range: match.range(at: 1)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.number], range: match.range(at: 2)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.number], range: match.range(at: 3)) } matches = stageRegex.matches(in: textStorage.string, options: [], range: range) for match in matches { - textStorage.addAttributes([.foregroundColor: NSColor.syntax.option], range: match.range(at: 1)) - textStorage.addAttributes([.foregroundColor: NSColor.syntax.number], range: match.range(at: 2)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.option], range: match.range(at: 1)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.number], range: match.range(at: 2)) + } + + matches = groupRegex.matches(in: textStorage.string, options: [], range: range) + + for match in matches { + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.option], range: match.range(at: 1)) + textStorage.addAttributes( + [.foregroundColor: NSColor.syntax.vertex], range: match.range(at: 2)) } } } struct MapTextEditor: NSViewControllerRepresentable { - @Binding var text: String + @Binding var document: MapDocument var onChange: () -> Void = {} func makeNSViewController( context: NSViewControllerRepresentableContext ) -> MapTextEditorController { - return MapTextEditorController(text: $text, onChange: onChange) + return MapTextEditorController(document: $document, onChange: onChange) } func updateNSViewController(